package pers.rcl.common.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.sql.SQLException;

/**
 * 全局异常处理器
 *
 * @Author LiuBao
 * @Version 2.0 2017年3月29日
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class GlobalExceptionAdvice {

    @Autowired
    private MessageSourceUtil messageSourceUtil;

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Object handleMissingServletRequestParameterException(HttpServletResponse response, MissingServletRequestParameterException exception) {
        log.error("缺少请求参数", exception);

        return "";
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Object handleHttpMessageNotReadableException(HttpServletResponse response, HttpMessageNotReadableException exception) {
        log.error("参数解析失败", exception);

        return "";
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BindException.class)
    public Object handleBindException(HttpServletResponse response, BindException exception) {
        log.error("参数绑定失败", exception);
        BindingResult result = exception.getBindingResult();

        return "";
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ConstraintViolationException.class)
    public Object handleConstraintViolationException(HttpServletResponse response, ConstraintViolationException exception) {
        log.error("参数Constraint验证失败", exception);

        return "";
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(ValidationException.class)
    public Object handleValidationException(HttpServletResponse response, ValidationException exception) {
        log.error("参数验证失败", exception);

        return "";
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Object handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpServletResponse response, HttpRequestMethodNotSupportedException exception) {
        String method = request.getMethod();
        log.error("不支持当前请求{}方法:{}", exception, method);

        return "";
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Object handleHttpMediaTypeNotSupportedException(HttpServletRequest request, HttpServletResponse response, HttpMediaTypeNotSupportedException exception) {
        String contentType = request.getContentType();
        log.error("不支持当前媒体类型[{}],error:{}", exception, contentType);

        return "";
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    public Object handleException(HttpServletResponse response, Exception exception) {
        log.error("通用异常", exception);

        return "";
    }


    /**
     * 数据库异常,请稍候重试!
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(SQLException.class)
    public Object handleSQLException(HttpServletResponse response, SQLException exception) {
        log.error("操作数据库出现异常:", exception);

        return "";
    }


    /**
     * 参数校验等相关异常
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(AuthParamException.class)
    public Object handleAuthParamException(HttpServletResponse response, AuthParamException exception) {

        return "";
    }


    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleMethodArgumentNotValidException(HttpServletResponse response, MethodArgumentNotValidException exception) {
        log.error("参数校验失败", exception);

        return "";
    }

    /**
     * MultipartException文件信息有问题
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MultipartException.class)
    public Object handleMultipartException(HttpServletResponse response, MultipartException exception) {
        log.error("MultipartException文件信息有问题", exception);

        return "";
    }

}